/*!
    \copyright  Copyright (c) 2024 - 2025 Qualcomm Technologies International, Ltd.
                All Rights Reserved.
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    \ingroup    bt
    \brief      This module is used to control relay of stereo/mono audio channels based on usecase and codec.
*/

#include "relay_control.h"
#include "logging.h"

#ifdef INCLUDE_MIRRORING

#ifdef INCLUDE_CIS_MIRRORING
#define RELAY_MODE_DEFAULT     (relay_usecase_media | relay_usecase_gaming | relay_usecase_voice | relay_usecase_live | relay_usecase_non_media)
#else
#define RELAY_MODE_DEFAULT      relay_usecase_none
#endif /* INCLUDE_CIS_MIRRORING */

/*! Relay state mask Data */
static uint32 relay_modes[relay_codec_type_max] = {RELAY_MODE_DEFAULT};

static bool relayControl_IsValidCodecType(relay_codec_type_t codec_type)
{
    bool is_valid = codec_type < relay_codec_type_max;

#if !defined(__QCC518X__) && !defined(__QCC308X__)
    if (codec_type == relay_codec_type_aptx_adaptive_r3)
    {
        is_valid = FALSE;
    }
#endif

    return is_valid;
}

UNITCODESECTION(KEEP)
uint32 RelayControl_GetRelayConfig(relay_codec_type_t codec_type)
{
    return relayControl_IsValidCodecType(codec_type) ? relay_modes[codec_type] : relay_usecase_none;
}

UNITCODESECTION(KEEP)
bool RelayControl_EnableRelay(uint32 usecases, relay_codec_type_t codec_type)
{
    bool status = FALSE;

#ifdef INCLUDE_CIS_MIRRORING

    if (relayControl_IsValidCodecType(codec_type))
    {
        relay_modes[codec_type] = relay_modes[codec_type] | usecases;
        status = TRUE;
    }

#else

    UNUSED(usecases);
    UNUSED(codec_type);

#endif

    return status;
}

UNITCODESECTION(KEEP)
bool RelayControl_DisableRelay(uint32 usecases, relay_codec_type_t codec_type)
{
    bool status = FALSE;

    if (relayControl_IsValidCodecType(codec_type))
    {
        relay_modes[codec_type] = relay_modes[codec_type] & (~usecases);
        status = TRUE;
    }

    return status;
}

UNITCODESECTION(KEEP)
relay_mode_t RelayControl_GetRelayMode(relay_usecase_t usecase, relay_codec_type_t codec_type)
{
    relay_mode_t relay_mode = relayControl_IsValidCodecType(codec_type) && relay_modes[codec_type] & usecase ? relay_mode_enabled : relay_mode_disabled;

    DEBUG_LOG_INFO("RelayControl_GetRelayMode relay_mode: enum:relay_mode_t:%d", relay_mode);

    return relay_mode;
}

UNITCODESECTION(KEEP)
relay_codec_type_t RelayControl_GetRelayCodecTypeFromLeAudioCodec(appKymeraLeAudioCodec le_audio_codec)
{
    relay_codec_type_t relay_codec = relay_codec_type_max;

    switch (le_audio_codec)
    {
        case KYMERA_LE_AUDIO_CODEC_LC3:
            relay_codec = relay_codec_type_lc3;
            break;

        case KYMERA_LE_AUDIO_CODEC_APTX_ADAPTIVE:
            relay_codec = relay_codec_type_aptx_adaptive_r3;
            break;

        default:
            break;
    }

    DEBUG_LOG_INFO("RelayControl_GetRelayCodecTypeFromLeAudioCodec codec_type: enum:appKymeraLeAudioCodec:%d, relay_codec: enum:relay_codec_type_t:%d",
                   le_audio_codec, relay_codec);

    return relay_codec;
}


relay_usecase_t RelayControl_GetUsecaseFromLeAudioContext(AudioContextType le_audio_context)
{
    relay_usecase_t usecase = relay_usecase_none;

    switch (le_audio_context)
    {
        case AUDIO_CONTEXT_TYPE_MEDIA:
            usecase = relay_usecase_media;
            break;

        case AUDIO_CONTEXT_TYPE_COVERSATIONAL:
            usecase = relay_usecase_voice;
            break;

        case AUDIO_CONTEXT_TYPE_GAME:
            usecase = relay_usecase_gaming;
            break;

        case AUDIO_CONTEXT_TYPE_LIVE:
            usecase = relay_usecase_live;
            break;

        case AUDIO_CONTEXT_TYPE_SOUND_EFFECTS:
            /* fall thru */
        case AUDIO_CONTEXT_TYPE_NOTIFICATIONS:
            usecase = relay_usecase_non_media;
            break;

        default:
            break;
    }

    DEBUG_LOG_INFO("RelayControl_GetUsecaseFromLeAudioContext le_audio_context: 0x%04x, usecase: enum:relay_usecase_t:%d",
                   le_audio_context, usecase);

    return usecase;
}

#endif /* INCLUDE_MIRRORING */
